﻿using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using Flow.Launcher.ViewModel;

namespace Flow.Launcher.Converters;

public class QuerySuggestionBoxConverter : IMultiValueConverter
{
    private static readonly string ClassName = nameof(QuerySuggestionBoxConverter);

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        // values[0] is TextBox: The textbox displaying the autocomplete suggestion
        // values[1] is ResultViewModel: Currently selected item in the list
        // values[2] is string: Query text
        if (
            values.Length != 3 ||
            values[0] is not TextBox queryTextBox ||
            values[1] is null ||
            values[2] is not string queryText ||
            string.IsNullOrEmpty(queryText)
        )
            return string.Empty;

        if (values[1] is not ResultViewModel selectedItem)
            return Binding.DoNothing;

        try
        {
            var selectedResult = selectedItem.Result;
            var selectedResultActionKeyword = string.IsNullOrEmpty(selectedResult.ActionKeywordAssigned) ? "" : selectedResult.ActionKeywordAssigned + " ";

            string selectedResultPossibleSuggestion = null;
            
            // Firstly check if the result has QuerySuggestionText
            if (!string.IsNullOrEmpty(selectedResult.QuerySuggestionText))
            {
                selectedResultPossibleSuggestion = selectedResultActionKeyword + selectedResult.QuerySuggestionText;

                // If this QuerySuggestionText does not start with the queryText, set it to null
                if (!selectedResultPossibleSuggestion.StartsWith(queryText, StringComparison.CurrentCultureIgnoreCase))
                {
                    selectedResultPossibleSuggestion = null;
                }
            }

            // Then check Title as suggestion
            if (string.IsNullOrEmpty(selectedResultPossibleSuggestion))
            {
                selectedResultPossibleSuggestion = selectedResultActionKeyword + selectedResult.Title;

                // If this QuerySuggestionText does not start with the queryText, set it to null
                if (!selectedResultPossibleSuggestion.StartsWith(queryText, StringComparison.CurrentCultureIgnoreCase))
                {
                    selectedResultPossibleSuggestion = null;
                }
            }

            if (string.IsNullOrEmpty(selectedResultPossibleSuggestion))
                return string.Empty;

            // For AutocompleteQueryCommand.
            // When user typed lower case and result title is uppercase, we still want to display suggestion
            selectedItem.QuerySuggestionText = string.Concat(queryText, selectedResultPossibleSuggestion.AsSpan(queryText.Length));

            // Check if Text will be larger than our QueryTextBox
            Typeface typeface = new Typeface(queryTextBox.FontFamily, queryTextBox.FontStyle, queryTextBox.FontWeight, queryTextBox.FontStretch);
            var dpi = VisualTreeHelper.GetDpi(queryTextBox);
            var ft = new FormattedText(
                queryTextBox.Text,
                CultureInfo.CurrentCulture,
                FlowDirection.LeftToRight,
                typeface,
                queryTextBox.FontSize,
                Brushes.Black,
                dpi.PixelsPerDip
            );

            var offset = queryTextBox.Padding.Right;

            if (ft.Width + offset > queryTextBox.ActualWidth || queryTextBox.HorizontalOffset != 0)
                return string.Empty;

            return selectedItem.QuerySuggestionText;
        }
        catch (Exception e)
        {
            App.API.LogException(ClassName, "fail to convert text for suggestion box", e);
            return string.Empty;
        }
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
